#! /usr/bin/env perl

use POSIX qw(strftime);

my $template_id;            #模板id
my $template_type;          #模板类型
my $template_group;         #模板组id
my $params_count;           #参数个数
my $init_flag;              #初始化命令标签标识
my $destory_flag;           #反初始化命令标签标识
my $baseline_flag;          #基线项标签标识
my $init_cmds;              #初始化命令
my $destory_cmds;           #反初始化命令

@arry_params_des = ();      #参数名字列表
@arry_params_lable = ();    #参数列表
@array_baseline_ids = ();   #基线项id列表
@array_check_ids = ();      #检查点id列表
@array_check_cmds = ();     #检查点命令列表
@all_check_cmds = ();       #检查点结果列表，数组嵌套数组，[[check_id1, check_cmd1,],[check_id1', check_cmd1',]]


#检查是否有传tag目标解析xml文件
if(@ARGV < 1){
    $msg = "linux.pl params error";
    $msg .= "初始xml文件地址";
    print "$msg\n";
    exit;
}

my $path_pwd = $ARGV[0];
#打开xml文件
my $xmlfile = $path_pwd;
$xmlfile .= '/';
$xmlfile .= $ARGV[1];
open my($fh), '<', $xmlfile or die "Cannot open $xmlfile:$!";

#对文件每行解析
while(<$fh>)
{
    #info标签获取模板id，模板类型，模板组id
    if ($_ =~ /<info/) {
        $_ =~/(.*)template_id="(.+?)"/;
        $template_id = $2;

        $_ =~/(.*)template_type="(.+?)"/;
        $template_type = $2;

        $_ =~/(.*)template_group="(.+?)"/;
        $template_group = $2;
    }
    #匹配参数
    elsif ($_ =~ /<params/)
    {
        $_ =~/(.*)count="(.+?)"/;
        $params_count = $2;
    }
    elsif ($_ =~ /<param /)
    {
        $_ =~/(.*)des="(.+?)"/;
        push(@arry_params_des, $2);
        $_ =~/(.*)lable="(.+?)"/;
        push(@arry_params_lable, $2);
    }
    elsif ($_ =~ /(.*)<init>(.*)/)
    {
        $_=~ s/(.*)<init><!\[CDATA\[/ /;
        $_=~ s/\]\]><\/init>(.*)/ /;
        $_ =~ s/^\s+//;         #去除前后空格
        $_ =~ s/\s+$//;         #去除前后空格
        $init_cmds = $_;
    }
    #匹配baseline标签
    elsif ($_ =~ /(.*)<baseline(.*)/)
    {
        $_ =~/(.*)id="(.+?)"/;
        $baseline_flag = 1;
        push(@array_baseline_ids, $2);
    }
    elsif ($_ =~ /(.*)baseline>/)
    {
        my $len=@array_check_ids;
        @tmp_check_cmds = ();
        for ($i = 0; $i < $len; $i = $i + 1)
        {
            push(@tmp_check_cmds, $array_check_ids[$i]);
            push(@tmp_check_cmds, $array_check_cmds[$i]);
        }
        push@all_check_cmds, [@tmp_check_cmds];

        $baseline_flag = undef;
        @array_check_ids = ();
        @array_check_cmds = ();
    }
    elsif ($baseline_flag == 1)
    {
        #单个基线项获取每个检查点id
        if ($_ =~ /(.*)<id>(.*)/)
        {
            $_=~ s/[(.*)<id>]//g;
            $_=~ s/[<\/id>(.*)]//g;
            $_ =~ s/\s+//g;         #去除前后空格
            push(@array_check_ids, $_);
        }
        #单个基线项获取每个检查点命令
        if ($_ =~ /(.*)<command>(.*)/)
        {
            $_=~ s/<command>/ /g;
            $_=~ s/<\/command>/ /g;
            $_=~ s/<!\[CDATA\[/ /g;
            $_=~ s/\]\]>/ /g;
            $_ =~ s/^\s+//;         #去除前后空格
            $_ =~ s/\s+$//;         #去除前后空格
            push(@array_check_cmds, $_);
        }
    }
    elsif ($_ =~ /(.*)<destory>(.*)/)
    {
        $_=~ s/(.*)<destory><!\[CDATA\[/ /;
        $_=~ s/\]\]><\/destory>(.*)/ /;
        $_ =~ s/^\s+//;         #去除前后空格
        $_ =~ s/\s+$//;         #去除前后空格
        $destory_cmds = $_;

    }
}


#检查传入参数个数
if(@ARGV != $params_count + 2){
    $msg = "linux.pl params error ";
    $msg .= "初始xml文件地址 ";
    for ($i = 0; $i < $params_count; $i = $i + 1)
    {
        $msg .= $arry_params_des[$i];
        $msg .= " ";
    }
    print "$msg\n";
    exit;
}


# 执行命令写入xml文件
sub generate_xml{
    my $date = strftime "%Y-%m-%d %H:%M:%S", localtime;    #时间
    chomp $date;
    my $ipaddr = "";
    my $ipaddr = `ifconfig | grep -oE 'inet( addr)?.([0-9]{1,3}\\.?){4}\\>' | grep -oE '([0-9]{1,3}\\.?){4}' | grep -v '^127' | head -n 1`;
    chomp $ipaddr;
    if(!$ipaddr){
    $ipaddr = "127.0.0.1";}

    sub add_baseline_begin{                                 #添加baseline开始标签
        my ($string, $baseline_id, $baseline_date)= @_;
        $string .= "\t".'<baseline id="'.$baseline_id.'" scan_time="'.$baseline_date.'">'."\n";
    return $string;}

    sub add_baseline_end{                                   #添加baseline结束标签
        my ($string)= @_;
        $string .= "\t".'</baseline>'."\n";
    return $string;}

    sub add_item{                                           #添加item检查点结果标签
        my ($string, $chck_id, $value)= @_;
        $string .= "\t\t".'<item id='.$chck_id.'>'."\n";
        $string .= "\t\t\t".'<value>';
        $string .= "<![CDATA[".$value."]]></value>\n";
        $string .= "\t\t</item>\n";
    return $string;}

    #替换字符串参数SST_SF{******}
    sub replace_params{
        my ($cmd,) = @_;
        for ($k = 0; $k < $params_count; $k = $k + 1)
        {
            $temp = 'SST_SF{'.$arry_params_lable[$k].'}';
            #含任何特殊符需要特殊转义
            $temp = quotemeta($temp);
            $cmd =~ s/$temp/$ARGV[$k + 2]/g;
        }
        return $cmd;
    }

    
    my $xml_string = "";
    $xml_string .='<?xml version="1.0" encoding="UTF-8"?>'."\n";
    $xml_string .= '<result ip= "'.$ipaddr.'" template_id= "'.$template_id.'" template_type = "'.$template_type.'" template_group= "'.$template_group.'" scan_time= "'.$date.'">'."\n";

    #print "***************checkpoint********************\n";
    #执行检查点命令,写入XML文件
    for ($i = 0; $i < @all_check_cmds; $i = $i + 1)
    {
        $baseline_date = strftime "%Y-%m-%d %H:%M:%S", localtime;    #时间
        chomp $baseline_date;
        $xml_string = &add_baseline_begin($xml_string, $array_baseline_ids[$i], $baseline_date);
        for ($j = 0; $j < @{$all_check_cmds[$i]}; $j = $j + 2)
        {
            $chck_id = ${$all_check_cmds[$i]}[$j];
            $chck_cmd = ${$all_check_cmds[$i]}[$j + 1];
            $chck_cmd = &replace_params($chck_cmd);
            # ####替换成\n
            $chck_cmd =~ s/####/\n/g;
            my $tmp_result = `$chck_cmd`;
            chomp $tmp_result;
            $tmp_result =~ s/>/&gt;/g;
            if ($tmp_result eq '')
            {
                $tmp_result = "SST_SF_NULL";
            }
            $xml_string = &add_item( $xml_string, $chck_id, $tmp_result );
        }
        $xml_string = &add_baseline_end($xml_string);
    }

    $xml_string .= "</result>"."\n";
	
    $module_name = $ARGV[1];
    $strlen = length $module_name;
    $res = substr($module_name, 0, $strlen - 4);
    if ($module_name =~ /_tag.xml\z/)
    {
        $res = substr($module_name, 0, $strlen - 8);
    }

    #$xmlfile = $path_pwd;
    #$xmlfile .= '/';
    $xmlfile_name = $ipaddr."_".$res."_chk.xml";
    $xmlfile_name =~ s/\s//g;        #全局替换空格为空
    $xmlfile_tmp .= $path_pwd."/".$xmlfile_name;
    print $xmlfile_tmp."\n";
    open XML,">".$xmlfile_tmp or die "Cannot create ip.xml:$!";
    print XML $xml_string;      #写入XML文件（注意这不是不是打印）
    print "end write xml\n";
    print "DONE ALL\n";

    #执行反初始化命令
    system($destory_cmds);
}
generate_xml();